﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Helpers;
using System.Xml;

namespace Credisoft.Models.Helpers
{
    public class BonitaConnector
    {
        public static int ID_INSTANTIATE_PROCESS = 0;
        public static int ID_INSTANTIATE_PROCESS_WITH_VARIABLES = 1;
        public static int ID_SET_PROCESS_VARIABLE = 2;
        public static int ID_START_TASK = 3;
        public static int ID_FINISH_TASK = 4;

        public static String PROCESS_ONE_INBOX_ASSIGNMENT = "Estacion1_JefeGrupoAsignar--1.0";
        public static String PROCESS_ONE_ANALYST = "Estacion1_Analista--1.0";
        public static String PROCESS_ONE_BOSS = "Estacion1_JefeGrupoPropio--1.0";
        public static String PROCESS_VERIFY_APROVEMENTS = "Verificacion_Aprobaciones_BackGround--1.0";


        public static String[] Servers = {
            "http://localhost:9090" , // LOCAL SERVER
            "http://200.16.7.113:8080" , // PUCP SERVER
            "http://192.168.2.17:8080" // AUXILIAR SERVER
        };

        private static String[] UrlRequests = {
       		"{0}/bonita-server-rest/API/runtimeAPI/instantiateProcess/{1}" ,
        	"{0}/bonita-server-rest/API/runtimeAPI/instantiateProcessWithVariables/{1}" ,
        	"{0}/bonita-server-rest/API/runtimeAPI/setActivityInstanceVariable/{1}" ,
            "{0}/bonita-server-rest/API/runtimeAPI/startTask/{1}--it1--mainActivityInstance--noLoop/true", // necesita ID
			"{0}/bonita-server-rest/API/runtimeAPI/finishTask/{1}--it1--mainActivityInstance--noLoop/true" , //necesita ID
            "http://localhost:9090/bonita-server-rest/API/runtimeAPI/finishTask/{0}--Aprobar_Estacion_Analista--it1--mainActivityInstance--noLoop/true" // necesita ID
		};

        public static String startProcess(String processString, int apiIdentifier, JObject variables = null, int serverId = 1)
        {
            var request = createRequest(processString, apiIdentifier, serverId);
            // Create the data we want to send   
            String data = "options=user:admin";
            String varString = getVariablesString(variables);
            data += varString;

            // Create a byte array of the data we want to send  
            byte[] byteData = UTF8Encoding.UTF8.GetBytes(data);

            // Set the content length in the request headers   
            request.ContentLength = byteData.Length;

            // Write data   
            using (Stream postStream = request.GetRequestStream())
            {
                postStream.Write(byteData, 0, byteData.Length);
            }

            return getResponse(request);
        }

        private static HttpWebRequest createRequest(String process, int apiIdentifier, int serverId)
        {
            // Create the URI Address
            String url = String.Format(UrlRequests[apiIdentifier], Servers[serverId], process);
            var address = new Uri(url);
            // Create the web request  
            var request = WebRequest.Create(address) as HttpWebRequest;

            // Set type to POST  
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.Headers.Add("Authorization", "Basic cmVzdHVzZXI6cmVzdGJwbQ==");
            return request;
        }

        private static String getResponse(HttpWebRequest request)
        {
            String uuid = "ERROR!";
            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                // Get the response stream  
                StreamReader reader = new StreamReader(response.GetResponseStream());
                XmlDocument xml = new XmlDocument();
                xml.LoadXml(reader.ReadToEnd());
                uuid = xml.InnerText;
            }
            return uuid;
        }

        private static String getVariablesString(JObject variables)
        {
            if (variables == null) return "";
            String parsedString = "&variables=";
            parsedString += "<map>";
            foreach (var value in variables) parsedString += getVariableTag(value);
            parsedString += "</map>";
            return parsedString;
        }

        private static String getVariableTag(KeyValuePair<String, JToken> property)
        {
            String key = property.Key.ToString(), value = property.Value.ToString(), tag = "";
            tag += "<string>" + key + "</string>";
            if (Utils.isDate(value)) tag += "<date>" + value + "</date>";
            else if (Utils.isBoolean(value)) tag += "<boolean>" + value + "</boolean>";
            else tag += "<string>" + value + "</string>";
            return "<entry>" + tag + "</entry>";
        }
    }
}
